package com.echo.im.client.handler.message;

import com.echo.im.common.model.BaseMessage;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author lxy
 * @date 2024-08-14
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class DefaultMessageHandlerFactory implements MessageHandlerFactory {


    private final Map<Class<? extends BaseMessage<?>>, MessageHandler<? extends BaseMessage<?>>> handlers = new HashMap<>();
    private final List<MessageHandler<? extends BaseMessage<?>>> messageHandlerList=new ArrayList<>();

    @PostConstruct
    public void init() {
        for (MessageHandler<? extends BaseMessage<?>> messageHandler : messageHandlerList) {
            Class<? extends BaseMessage<?>> messageType = extractMessageType(messageHandler);
            if (messageType != null) {
                handlers.put(messageType, messageHandler);
            } else {
                log.warn("Cannot determine the generic type of the message handler: {}", messageHandler.getClass());
            }
        }
    }

    @Override
    public MessageHandler<? extends BaseMessage<?>> getHandler(Class<? extends BaseMessage<?>> messageType) {
        return handlers.get(messageType);
    }

    private <T extends BaseMessage<?>> Class<T> extractMessageType(MessageHandler<T> handler) {
        return (Class<T>) ((ParameterizedType) handler.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0];
    }
}
